package common.project.epic.ui;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.protocol.HTTP;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Looper;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class CreateAccount extends Activity implements OnClickListener {
	
	public static final String TAG = "Epic: Login Activity";
    public static final boolean DEBUG = EpicDebugUI.DEBUG;
    
    private EditText create_account_name_ET;
    private EditText create_account_surname_ET;
    private EditText create_account_nickname_ET;
    private EditText create_account_psw_ET;
    private EditText create_account_psw_rpt_ET;
    private EditText create_account_email_ET;
    private Button create_account_register_button;
    private TextView create_account_psw_rpt_TV;
    private TextView create_account_email_TV;
    private TextView eula_TV;
    private CheckBox eula_CB;
    private static boolean eula_CB_flag;
    private ProgressDialog progressDialog;
    private static final String UPDATE_URL = "http://www.epic.vidaleluca.com/register.php";
    private static final String NUMBER_OF_ACCOUNTS = "number_of_accounts";
    public static final String PREF_FILE = "ApplicationPreferencesFile";
    public static String CURRENT_PREF_FILE = "";
    private SharedPreferences pref;
//    private Dialog dialogEula;
    private static final int EULA_INT = 1;
	private static Typeface tfNormal;
	private static Typeface tfBold;
	//value submitted to server to perfrom registration
	private static String nickname;
	private static String pass;
	private static String name;
	private static String surname;
	private static String email;
	
	
	
    public String EMAIL_REGEXP = "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
    "\\@" +
    "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
    "(" +
    "\\." +
    "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
    ")+";
    public final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
            "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
            "\\@" +
            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
            "(" +
            "\\." +
            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
            ")+"
        );

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	    setContentView(R.layout.create_account);
	    if(DEBUG) {
    		Log.d(TAG, "onCreate()");
	    }
	    //set the external fonts
	    tfNormal = Typeface.createFromAsset(getBaseContext().getAssets(), "font/Arial.ttf");
	    tfBold = Typeface.createFromAsset(getBaseContext().getAssets(), "font/ArialBold.ttf");
	    eula_CB_flag = false;
	    //set up view instances
	    create_account_name_ET = (EditText)findViewById(R.id.create_account_name_ET);
		create_account_surname_ET = (EditText)findViewById(R.id.create_account_surname_ET);
		create_account_email_ET = (EditText)findViewById(R.id.create_account_email_ET);
		create_account_psw_ET = (EditText)findViewById(R.id.create_account_psw_ET);
		create_account_psw_rpt_ET = (EditText)findViewById(R.id.create_account_psw_rpt_ET);
		create_account_nickname_ET = (EditText)findViewById(R.id.create_account_nickname_ET);
		create_account_register_button = (Button)findViewById(R.id.create_account_register_button);
		create_account_register_button.setClickable(false);
		create_account_psw_rpt_TV = (EditText) findViewById(R.id.create_account_psw_rpt_ET);
	    eula_TV = (TextView)findViewById(R.id.eula_text);
	    eula_CB = (CheckBox)findViewById(R.id.eula_checkBox);
		//set the external font
		create_account_name_ET.setTypeface(tfNormal);
		create_account_surname_ET.setTypeface(tfNormal);
		create_account_nickname_ET.setTypeface(tfNormal);
		create_account_psw_ET.setTypeface(tfNormal);
		create_account_psw_rpt_ET.setTypeface(tfNormal);
		create_account_email_ET.setTypeface(tfNormal);
	    eula_TV.setTypeface(tfBold);
	    
	    
		//Set up of progress dialog
		progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Please wait...");
        progressDialog.setIndeterminate(true);
        progressDialog.setCancelable(false);
        eula_CB.setOnCheckedChangeListener(new OnCheckedChangeListener(){
		@Override
		public void onCheckedChanged(CompoundButton buttonView,
				boolean isChecked) {
				eula_CB_flag = isChecked;	
		}
        });
		eula_TV.setOnClickListener(this);
	    create_account_psw_rpt_ET.setOnFocusChangeListener(new OnFocusChangeListener() {
	    	@Override
	    	public void onFocusChange(View v, boolean hasFocus) {
	    		String psw = create_account_psw_rpt_ET.getText().toString();
    			String psw_rpt = create_account_psw_ET.getText().toString();
	    		if(!psw.equals("") && !hasFocus){
	    		if(v.getId()==R.id.create_account_psw_rpt_ET){
	    			
	    			
	    			
	    	    	if(!psw.equals(psw_rpt)){
	    	    			create_account_psw_rpt_ET.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
	    	    			create_account_psw_rpt_TV.setTextColor(getResources().getColor(R.color.Red));
	    	    			create_account_psw_rpt_TV.setText(R.string.psw_not_match);
	    	    			
	    	    		}else if(psw.equals(psw_rpt)){
	    	    		
//	    	    			create_account_psw_rpt_TV.setTextColor(getResources().getColor(R.color.White));
//	    	    			create_account_psw_rpt_TV.setText(R.string.password_rpt);
	    	    		
	    	    		}
	    	    	}
	    	    }
	    		if(v.getId()==R.id.create_account_psw_ET){
	    			
	    			create_account_psw_rpt_TV.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
	    	    }
	    	}});
	    create_account_psw_ET.setOnFocusChangeListener(new OnFocusChangeListener() {
	    	@Override
	    	public void onFocusChange(View v, boolean hasFocus) {
	    		
	    		if(v.getId()==R.id.create_account_psw_ET){
	    			
	    			create_account_psw_ET.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
	    	    }
	    	}});
	    create_account_email_ET.setOnFocusChangeListener(new OnFocusChangeListener() {
	    	public void onFocusChange(View v, boolean hasFocus) {
	    		String email_test = create_account_email_ET.getText().toString();
	    	    if(!email_test.equals("") && !hasFocus){
	    	    	if(v.getId()==R.id.create_account_email_ET){
	    	    	if(!eMailValidation(create_account_email_ET.getText().toString())){
	    	    		
		    	    	create_account_email_ET.setTextColor(getResources().getColor(R.color.Red));
//		    	    	create_account_email_ET.setText(R.string.bad_email);
	    	    		
	    	    	}else{
	    	    		
	    	    		create_account_email_ET.setTextColor(getResources().getColor(R.color.White));
//	    	    		create_account_email_ET.setText(R.string.email);
	    	    		
	    	    	}
	    	    }
	    	    }
	    	}});

	    
	    create_account_register_button.setOnClickListener(new OnClickListener(){
	    	
			@Override
			public void onClick(View v) {
				if(!eula_CB_flag){
					createDialog("Error","Please first accept privacy policy and fill registration form with valid data");
				}else{
					int name_size = create_account_name_ET.getText().length();
	                int surname_size = create_account_surname_ET.getText().length();
					int user_size = create_account_nickname_ET.getText().length();
	                int pass_size = create_account_psw_ET.getText().length();
	                int pass_rpt_size = create_account_psw_rpt_ET.getText().length();
	                int email_size = create_account_email_ET.getText().length();
	                if(user_size > 0 && pass_size > 0 && pass_rpt_size > 0 && email_size > 0 
	                		&& name_size > 0 && surname_size > 0 && eMailValidation(create_account_email_ET.getText().toString())) {
	                	 
	                    progressDialog.show();
	 
	                    nickname = create_account_nickname_ET.getText().toString();
	                    pass = create_account_psw_ET.getText().toString();
	                    name = create_account_name_ET.getText().toString();
	                    surname = create_account_surname_ET.getText().toString();
	                    email = create_account_email_ET.getText().toString();
	                    String interest = "1111000000000000";
	                    
	                    doRegister(nickname, pass, name, surname, email, interest);
	 
	                } else{
	                	createDialog("Error","Please fill registration form with valid data");
	                }
 
            }
			
			}
	    	
	    } );
	    
	}
	
	private void doRegister(final String nickname, final String pass, final String name, final String surname, final String email, final String interests) {
		 
        final String password_md5 = md5(pass);
        
        Thread t = new Thread() {
 
            public void run() {
 
                Looper.prepare();
 
                DefaultHttpClient client = new DefaultHttpClient();
 
                HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);                
 
                HttpResponse response;
 
                HttpEntity entity;        
 
                try {
 
                    HttpPost post = new HttpPost(UPDATE_URL);
 
                    List <NameValuePair> nvps = new ArrayList <NameValuePair>();
 
                    nvps.add(new BasicNameValuePair("nickname", nickname));
 
                    nvps.add(new BasicNameValuePair("password", password_md5));
                    
                    nvps.add(new BasicNameValuePair("name", name));
                    
                    nvps.add(new BasicNameValuePair("surname", surname));
                    
                    nvps.add(new BasicNameValuePair("email", email));
                   
                    nvps.add(new BasicNameValuePair("interests", interests.toString()));
                    
                    Log.d("CREATE PROFILE - POST ", nvps.toString());                   
                    
                    post.setHeader("Content-Type", "application/x-www-form-urlencoded");
 
                    post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
 
                    response = client.execute(post);
 
                    entity = response.getEntity();
 
                    InputStream is = entity.getContent();
 
                    read(is);
 
                    is.close();
 
                    if (entity != null) entity.consumeContent();
                    
                } catch (Exception e) {
 
                    progressDialog.dismiss();
 
                    createDialog("Error", "Couldn't establish a connection");
                    
 
                }
 
                Looper.loop();                
 
            }
 
        };
 
        t.start();
 
    }

	//create a alert dialog
	//@params String
	//@params String
	
    private void createDialog(String title, String text) {
    	 
        AlertDialog ad = new AlertDialog.Builder(this)
 
        .setPositiveButton("Ok", null)
 
        .setTitle(title)
 
        .setMessage(text)
 
        .create();
 
        ad.show();
 
    }
    
	// Read an input stream and pass it to LoginContentHandler
    //@params InputStream
    
    private void read(InputStream in) {
    	 
        SAXParserFactory spf = SAXParserFactory.newInstance();
 
        SAXParser sp;
 
        try {
 
            sp = spf.newSAXParser();
 
            XMLReader xr = sp.getXMLReader();
 
            RegisterContentHandler uch = new RegisterContentHandler();
 
            xr.setContentHandler(uch);
 
            xr.parse(new InputSource(in));
 
        } catch (ParserConfigurationException e) {
 
        } catch (SAXException e) {
 
        } catch (IOException e) {}
 
    }  
	

    private class RegisterContentHandler extends DefaultHandler {
 
        private boolean in_registerTag = false;
 
        private int userID;
 
        private boolean error_occured = false;
 
 
 
        public void startElement(String n, String l, String q, Attributes a)
 
            throws SAXException {
 
            if(l == "register") {
            	in_registerTag = true;  
            	pref = getSharedPreferences(PREF_FILE,MODE_PRIVATE);
            	int noa = pref.getInt(NUMBER_OF_ACCOUNTS,0);
            	noa =  noa+1;
            	pref.edit()
            	.putInt(NUMBER_OF_ACCOUNTS, noa)
            	.putString("username_"+noa, create_account_email_ET.getText().toString())
            	.putString("password_"+noa, md5(create_account_psw_ET.getText().toString()))
            	.commit();
            }
 
            if(l == "error") {
 
                progressDialog.dismiss();
                
                if(Integer.parseInt(a.getValue("value")) == 1)
 
                    createDialog("Error", "Couldn't connect to Database");
 
                if(Integer.parseInt(a.getValue("value")) == 2)
 
                    createDialog("Error", "Error in Database: Table missing");
 
                if(Integer.parseInt(a.getValue("value")) == 3)
 
                    createDialog("Error", "Adding profile problem");
                
                if(Integer.parseInt(a.getValue("value")) == 4)
                	 
                    createDialog("Error", "Please change your username");
 
                error_occured = true;
 
            }
 
            if(l == "user" && in_registerTag && a.getValue("id") != "")            
 
                userID = Integer.parseInt(a.getValue("id"));
            	
        }
 
         
 
        public void endElement(String n, String l, String q) throws SAXException {
        	if(!error_occured){
	            if(l == "register") {
	 
	                in_registerTag = false;
	                
	                if(!error_occured) {
	                	
	                    progressDialog.dismiss();
	                    CURRENT_PREF_FILE = email;
	                    SharedPreferences sp = getSharedPreferences(CURRENT_PREF_FILE, MODE_PRIVATE);
	                    float defaultRate = (float) 3;
	                    sp.edit().putString("name", name).putString("surname", surname).putString("currentNickname", nickname).putFloat("userRate", defaultRate).commit();
	                    Intent i = new Intent(getApplicationContext(),Login.class);
	                    i.putExtra("username", create_account_email_ET.getText().toString());
	                    i.putExtra("password", create_account_psw_ET.getText().toString());
	                    quit(true,i);
	                    
	                }
	                progressDialog.dismiss();
	            }
        	}
        else{
        	progressDialog.dismiss();
        }
        	
        	
        }
 
         
 
        public void  characters(char ch[], int start, int length) { }
 
        public void startDocument() throws SAXException { }
 
        public void endDocument() throws SAXException { }
 
    	}

    	
    private void quit(boolean success, Intent i) {
    	 
        //TODO return to login activity
    	if(success){
    		
    		startActivity(i);
    		
    	}
    }
	
	//generate md5 digest
	//@params String
	
	private String md5(String in) {
		 
        MessageDigest digest;
 
        try {
 
            digest = MessageDigest.getInstance("MD5");
 
            digest.reset();        
 
            digest.update(in.getBytes());
 
            byte[] a = digest.digest();
 
            int len = a.length;
 
            StringBuilder sb = new StringBuilder(len << 1);
 
            for (int i = 0; i < len; i++) {
 
                sb.append(Character.forDigit((a[i] & 0xf0) >> 4, 16));
 
                sb.append(Character.forDigit(a[i] & 0x0f, 16));
 
            }
 
            return sb.toString();
 
        } catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
 
        return null;
 
    }
	
	public boolean eMailValidation(String emailstring)
    {
        Pattern emailPattern = Pattern.compile(".+@.+\\.[a-z]+");
        Matcher emailMatcher = emailPattern.matcher(emailstring);
        return emailMatcher.matches();
    }
	
	@Override
	protected Dialog onCreateDialog(int id){
		if(id == EULA_INT){
			Dialog dialogEula;
			dialogEula = new Dialog(this);
			dialogEula.setContentView(R.layout.eula_dialog);
			dialogEula.setTitle("Privacy");
			return dialogEula;
		}
		return super.onCreateDialog(id);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if(v.getId() == R.id.eula_text){
			try{
				this.showDialog(EULA_INT);
			}
			catch(Exception e){e.printStackTrace();}
		}
	}
	
}
